<template>
  <n-tooltip trigger="hover">
    <template #trigger>
      <div class="cursor-pointer table-toolbar-right-icon">
        <n-popover trigger="click" :width="230" class="toolbar-popover" placement="bottom-end">
          <template #trigger>
            <n-icon size="18">
              <SettingOutlined />
            </n-icon>
          </template>
          <template #header>
            <div class="table-toolbar-inner-popover-title">
                <n-checkbox v-model:checked="checkAll" @update:checked="onCheckAll"
                  >列展示</n-checkbox
                >
                <n-button text type="info" size="small" class="mt-1" @click="resetColumns"
                  >重置</n-button
                >
            </div>
          </template>
          <div class="table-toolbar-inner">
            <n-checkbox-group v-model:value="checkList" @update:value="onChange">
              <Draggable
                v-model="columnsList"
                animation="300"
                item-key="key"
                filter=".no-draggable"
                :move="onMove"
                @end="draggableEnd"
              >
                <template #item="{ element }">
                  <div
                    class="table-toolbar-inner-checkbox"
                    :class="{
                      'table-toolbar-inner-checkbox-dark': getDarkTheme === true,
                      'no-draggable': element.draggable === false,
                    }"
                  >
                    <span
                      class="drag-icon"
                      :class="{ 'drag-icon-hidden': element.draggable === false }"
                    >
                      <n-icon size="18">
                        <DragOutlined />
                      </n-icon>
                    </span>
                    <n-checkbox :value="element.key" :label="element.title" />
                    <div class="fixed-item">
                      <n-tooltip trigger="hover" placement="bottom">
                        <template #trigger>
                          <n-icon
                            size="18"
                            :color="element.fixed === 'left' ? '#2080f0' : undefined"
                            class="cursor-pointer"
                            @click="fixedColumn(element, 'left')"
                          >
                            <VerticalRightOutlined />
                          </n-icon>
                        </template>
                        <span>固定到左侧</span>
                      </n-tooltip>
                      <n-divider vertical />
                      <n-tooltip trigger="hover" placement="bottom">
                        <template #trigger>
                          <n-icon
                            size="18"
                            :color="element.fixed === 'right' ? '#2080f0' : undefined"
                            class="cursor-pointer"
                            @click="fixedColumn(element, 'right')"
                          >
                            <VerticalLeftOutlined />
                          </n-icon>
                        </template>
                        <span>固定到右侧</span>
                      </n-tooltip>
                    </div>
                  </div>
                </template>
              </Draggable>
            </n-checkbox-group>
          </div>
        </n-popover>
      </div>
    </template>
    <span>列设置</span>
  </n-tooltip>
</template>

<script lang="ts">
  import { ref, defineComponent, reactive, unref, computed, toRaw, toRefs, watchEffect,PropType } from 'vue';
  import type {DataTableColumn,DataTableBaseColumn,DataTableColumnKey} from 'naive-ui';
  import {
    SettingOutlined,
    DragOutlined,
    VerticalRightOutlined,
    VerticalLeftOutlined,
  } from '@vicons/antd';
  import Draggable from 'vuedraggable';
  import { useDesignSettingStore } from '@/store/modules/designSetting';

  interface IColumnSetting {
    checkAll: boolean;
    checkList: DataTableColumnKey[];
  }

  export default defineComponent({
    name: 'ColumnSettings',
    components: {
      SettingOutlined,
      DragOutlined,
      Draggable,
      VerticalRightOutlined,
      VerticalLeftOutlined,
    },
    emits:['change'],
    props:{
      tableColumns:{
        type:Array as PropType<Array<DataTableColumn>>,
        defult:()=>[]
      }
    },
    setup(props,{emit}) {
      const designStore = useDesignSettingStore();
      const getDarkTheme = computed(() => designStore.darkTheme);
      const columnsList = ref<Array<DataTableColumn>>([]);

      const state = reactive<IColumnSetting>({
        checkAll: true,
        checkList: []
      });

      watchEffect(() => {
        columnsList.value = toRaw(props.tableColumns) as Array<DataTableColumn>;
        state.checkList = (props.tableColumns as Array<DataTableColumn>).map((item:DataTableBaseColumn)=>item.key);
      });

      //切换
      const onChange = (checkList:DataTableColumnKey[]):void => {
        const newColumns:Array<DataTableColumn> = [];
        for(const item of columnsList.value){
          if(checkList.includes((item as DataTableBaseColumn).key)){
            newColumns.push(toRaw(item));
          }
        }
        emit('change',newColumns);
      }

      //重置
      const resetColumns = ():void => {
        columnsList.value = toRaw(props.tableColumns) as Array<DataTableColumn>;
        state.checkAll = true;
        state.checkList = columnsList.value.map((item:DataTableBaseColumn)=>item.key);
        emit('change',toRaw(unref(columnsList)));
      }

      //全选
      const onCheckAll = (checked:boolean):void => {
        const newColumns:Array<DataTableColumn> = [];
        if(checked){
          state.checkList = columnsList.value.map((item:DataTableBaseColumn)=>item.key);
          for(const cItem of state.checkList){
            newColumns.push(toRaw(columnsList.value.find((item:DataTableBaseColumn)=>item.key===cItem)) as DataTableColumn)
          }
        }else{
          state.checkList = [];
        }
        emit('change',newColumns);
      }

      //拖拽排序
      const draggableEnd = ():void => {
        const newColumns:Array<DataTableColumn> = [];
        for(const item of columnsList.value){
          if(state.checkList.includes((item as DataTableBaseColumn).key)){
            newColumns.push(toRaw(item));
          }
        }
        emit('change',newColumns);
      }

      const onMove = (e):boolean => {
        if (e.draggedContext.element.draggable === false) return false;
        return true;
      }

      //固定
      const fixedColumn = (item:DataTableColumn, fixed:'left'|'right'|undefined):void => {
        if (!state.checkList.includes((item as DataTableBaseColumn).key)) return;
        const itemFixed = item.fixed === fixed ? undefined : fixed;
        item.fixed = itemFixed;
        const newColumns:Array<DataTableColumn> = [];
        for(const item of columnsList.value){
          newColumns.push(toRaw(item))
        }
        emit('change',newColumns);
      }

      return {
        ...toRefs(state),
        columnsList,
        getDarkTheme,
        onChange,
        onCheckAll,
        onMove,
        resetColumns,
        fixedColumn,
        draggableEnd,
      };
    },
  });
</script>

<style lang="less">
  .table-toolbar {
    &-inner-popover-title {
      padding: 3px 0;
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      align-items: center;
    }

    &-right {
      &-icon {
        margin-left: 12px;
        font-size: 16px;
        color: var(--text-color);
        cursor: pointer;

        :hover {
          color: #1890ff;
        }
      }
    }
  }

  .table-toolbar-inner {
    &-checkbox {
      display: flex;
      align-items: center;
      padding: 10px 14px;

      &:hover {
        background: #e6f7ff;
      }

      .drag-icon {
        display: inline-flex;
        margin-right: 8px;
        cursor: move;
        &-hidden {
          visibility: hidden;
          cursor: default;
        }
      }

      .fixed-item {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        margin-left: auto;
      }

      .ant-checkbox-wrapper {
        flex: 1;

        &:hover {
          color: #1890ff !important;
        }
      }
    }

    &-checkbox-dark {
      &:hover {
        background: hsla(0, 0%, 100%, 0.08);
      }
    }
  }

  .toolbar-popover {
    .n-popover__content {
      padding: 0;
    }
  }
</style>
